<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title> new document </title>
    <meta name="generator" content="editplus" />
    <meta name="author" content="" />
    <meta name="keywords" content="" />
    <meta name="description" content="" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="jquery-1.8.3.min.js" type="text/javascript"></script>
    <style type="text/css">
        footer {
            text-align: center;
            background-color: #1c1c1d;
            padding: 2px;
        }

        footer.fixed-bottom {
            position: fixed;
            bottom: 0;
            width: 100%;
        }

        footer p {
            margin: 3px;
            font-size: 10px;
            color: white;
        }

        .status {
            position: fixed;
            bottom: 0;
            background-color: #1c1c1d;
            margin: 3px;
            padding: 2px;
            font-size: 10px;
            color: white;
        }
    </style>
</head>

<body>


<center>
    <h3>websocket连接测试</h3>
    <textarea id="text" cols="50" rows="5"></textarea>
    <button onclick="send()">发送消息</button>
</center>
    <hr/>
    <button onclick="closeWebSocket()">关闭WebSocket连接</button>
    <hr/>
    <div id="message"></div>
</body>
<footer class="fixed-bottom">
    <div id="status" class="status"></div>
    <p>Powered by ForeverWin</p>
</footer>
<script type="text/javascript">
    var wsUrl = "ws://localhost:8081/websocket?channel=123";
    var websocket = null;
    var lockReconnect = false;  //避免ws重复连接

    createWebSocket(wsUrl);

    function createWebSocket(url) {
        try{
            //判断当前浏览器是否支持WebSocket
            if ('WebSocket' in window) {
                websocket = new WebSocket(wsUrl);
            }
            else {
                alert('当前浏览器 Not support websocket')
            }
            initEventHandle();
        }catch(e){
            reconnect(url);
            console.log(e);
        }
    }

    function initEventHandle() {
        //连接发生错误的回调方法
        websocket.onerror = function (event) {
            console.log(event);
            reconnect(wsUrl);
            setStatusInnerHTML("WebSocket连接发生错误");
        };
        //连接成功建立的回调方法
        websocket.onopen = function () {
            heartCheck.reset().start();      //心跳检测重置
            setStatusInnerHTML("WebSocket连接成功");
        };
        //接收到消息的回调方法
        websocket.onmessage = function (event) {
            console.log(event.data);
            heartCheck.reset().start();      //心跳检测重置
            if(event.data!='pong'){
                setMessageInnerHTML(event.data);
            }
        };
        //连接关闭的回调方法
        websocket.onclose = function (event) {
            console.log(event);
            reconnect(wsUrl);
            setStatusInnerHTML("WebSocket连接关闭");
        };
    }

    //监听窗口关闭事件，当窗口关闭时，主动去关闭websocket连接，防止连接还没断开就关闭窗口，server端会抛异常。
    window.onbeforeunload = function () {
        closeWebSocket();
    }
    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }
    //将状态显示在网页上
    function setStatusInnerHTML(innerHTML) {
        document.getElementById('status').innerHTML = "状态：" + innerHTML;
    }
    //关闭WebSocket连接
    function closeWebSocket() {
        websocket.close();
    }
    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }

    function reconnect(url) {
        if(lockReconnect) return;
        lockReconnect = true;
        setTimeout(function () {     //没连接上会一直重连，设置延迟避免请求过多
            createWebSocket(url);
            lockReconnect = false;
        }, 2000);
    }

    //心跳检测
    var heartCheck = {
        timeout: 1000,        //1分钟发一次心跳
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function(){
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function(){
            var self = this;
            this.timeoutObj = setTimeout(function(){
                //这里发送一个心跳，后端收到后，返回一个心跳消息，
                //onmessage拿到返回的心跳就说明连接正常
                websocket.send("ping");
                console.log("ping!");
                self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置，说明后端主动断开了
                    websocket.close();     //如果onclose会执行reconnect，我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
                }, self.timeout)
            }, this.timeout)
        }
    }
</script>
</html>